﻿#region

using System.Linq.Expressions;

#endregion

namespace Vin.Tool.Core.ExpressionCategory;

public static partial class Extension
{
    public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> self, Expression<Func<T, bool>> other,
        bool isAnd = true)
    {
        return !isAnd
            ? self
            : Expression.Lambda<Func<T, bool>>(Expression.AndAlso(self.Body, other.Body), self.Parameters);
    }

    public static Expression<Func<T, T2, bool>> And<T, T2>(this Expression<Func<T, T2, bool>> self,
        Expression<Func<T, T2, bool>> other, bool isAnd = true)
    {
        return !isAnd
            ? self
            : Expression.Lambda<Func<T, T2, bool>>(Expression.AndAlso(self.Body, other.Body), self.Parameters);
    }

    public static Expression<Func<T, T2, T3, bool>> And<T, T2, T3>(this Expression<Func<T, T2, T3, bool>> self,
        Expression<Func<T, T2, T3, bool>> other, bool isAnd = true)
    {
        return !isAnd
            ? self
            : Expression.Lambda<Func<T, T2, T3, bool>>(Expression.AndAlso(self.Body, other.Body), self.Parameters);
    }

    public static Expression<Func<T, T2, T3, T4, bool>> And<T, T2, T3, T4>(
        this Expression<Func<T, T2, T3, T4, bool>> self,
        Expression<Func<T, T2, T3, T4, bool>> other, bool isAnd = true)
    {
        return !isAnd
            ? self
            : Expression.Lambda<Func<T, T2, T3, T4, bool>>(Expression.AndAlso(self.Body, other.Body), self.Parameters);
    }

    public static Expression<Func<T, T2, T3, T4, T5, bool>> And<T, T2, T3, T4, T5>(
        this Expression<Func<T, T2, T3, T4, T5, bool>> self,
        Expression<Func<T, T2, T3, T4, T5, bool>> other, bool isAnd = true)
    {
        return !isAnd
            ? self
            : Expression.Lambda<Func<T, T2, T3, T4, T5, bool>>(Expression.AndAlso(self.Body, other.Body),
                self.Parameters);
    }

    public static Expression<Func<T, T2, T3, T4, T5, T6, bool>> And<T, T2, T3, T4, T5, T6>(
        this Expression<Func<T, T2, T3, T4, T5, T6, bool>> self,
        Expression<Func<T, T2, T3, T4, T5, T6, bool>> other, bool isAnd = true)
    {
        return !isAnd
            ? self
            : Expression.Lambda<Func<T, T2, T3, T4, T5, T6, bool>>(Expression.AndAlso(self.Body, other.Body),
                self.Parameters);
    }

    public static Expression<Func<T, T2, T3, T4, T5, T6, T7, bool>> And<T, T2, T3, T4, T5, T6, T7>(
        this Expression<Func<T, T2, T3, T4, T5, T6, T7, bool>> self,
        Expression<Func<T, T2, T3, T4, T5, T6, T7, bool>> other, bool isAnd = true)
    {
        return !isAnd
            ? self
            : Expression.Lambda<Func<T, T2, T3, T4, T5, T6, T7, bool>>(Expression.AndAlso(self.Body, other.Body),
                self.Parameters);
    }

    public static Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, bool>> And<T, T2, T3, T4, T5, T6, T7, T8>(
        this Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, bool>> self,
        Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, bool>> other, bool isAnd = true)
    {
        return !isAnd
            ? self
            : Expression.Lambda<Func<T, T2, T3, T4, T5, T6, T7, T8, bool>>(Expression.AndAlso(self.Body, other.Body),
                self.Parameters);
    }

    public static Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, bool>> And<T, T2, T3, T4, T5, T6, T7, T8, T9>(
        this Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, bool>> self,
        Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, bool>> other, bool isAnd = true)
    {
        return !isAnd
            ? self
            : Expression.Lambda<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, bool>>(
                Expression.AndAlso(self.Body, other.Body),
                self.Parameters);
    }

    public static Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, bool>> And<T, T2, T3, T4, T5, T6, T7, T8, T9,
        T10>(
        this Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, bool>> self,
        Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, bool>> other, bool isAnd = true)
    {
        return !isAnd
            ? self
            : Expression.Lambda<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, bool>>(
                Expression.AndAlso(self.Body, other.Body),
                self.Parameters);
    }

    public static Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, bool>> And<T, T2, T3, T4, T5, T6, T7, T8,
        T9, T10, T11>(
        this Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, bool>> self,
        Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, bool>> other, bool isAnd = true)
    {
        return !isAnd
            ? self
            : Expression.Lambda<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, bool>>(
                Expression.AndAlso(self.Body, other.Body),
                self.Parameters);
    }

    public static Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, bool>> And<T, T2, T3, T4, T5, T6,
        T7, T8, T9, T10, T11, T12>(
        this Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, bool>> self,
        Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, bool>> other, bool isAnd = true)
    {
        return !isAnd
            ? self
            : Expression.Lambda<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, bool>>(
                Expression.AndAlso(self.Body, other.Body),
                self.Parameters);
    }

    public static Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, bool>> And<T, T2, T3, T4, T5,
        T6, T7, T8, T9, T10, T11, T12, T13>(
        this Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, bool>> self,
        Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, bool>> other, bool isAnd = true)
    {
        return !isAnd
            ? self
            : Expression.Lambda<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, bool>>(
                Expression.AndAlso(self.Body, other.Body),
                self.Parameters);
    }

    public static Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, bool>> And<T, T2, T3, T4,
        T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(
        this Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, bool>> self,
        Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, bool>> other, bool isAnd = true)
    {
        return !isAnd
            ? self
            : Expression.Lambda<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, bool>>(
                Expression.AndAlso(self.Body, other.Body),
                self.Parameters);
    }

    public static Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, bool>> And<T, T2, T3,
        T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(
        this Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, bool>> self,
        Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, bool>> other,
        bool isAnd = true)
    {
        return !isAnd
            ? self
            : Expression.Lambda<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, bool>>(
                Expression.AndAlso(self.Body, other.Body),
                self.Parameters);
    }

    public static Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, bool>> And<T,
        T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(
        this Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, bool>> self,
        Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, bool>> other,
        bool isAnd = true)
    {
        return !isAnd
            ? self
            : Expression.Lambda<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, bool>>(
                Expression.AndAlso(self.Body, other.Body),
                self.Parameters);
    }
}